#!/usr/bin/perl
# Version 0.2.1

$testcase = "lsa_request_retr";

# 1 = PASS
# 2 = FAIL
# 3 = INCONCLUSIVE
$verdict = 3;

$dumpfile = "$testcase.dump";
$logfile = "$testcase.log";

if ($#ARGV ne 2) {
        print("Usage: $testcase.pl dump_file1 dump_file2 log_file");
        exit 1;
}

$dumpfile1 = $ARGV[0];
$dumpfile2 = $ARGV[1];
$logfile = $ARGV[2];

#------------------------------------------------------------------------------

@local_verdict = ( 3, 3 );

$success = 1;
$state = 0;

open(DUMPFILE, $dumpfile1) or $success = 0;

if($success eq 1) {
	
	$last_retr = 0;
	
	while(<DUMPFILE>) {
		# wait 100 s for TR's LSDB to fill
		if($state eq 0) {
			@l = split(/ /, $_);
		
			# now look at the time
			@ti = split(/\./, $l[0]);
			@ts = split(/:/, $ti[0]);
			
			$secs = $ts[2] + ($ts[1] + $ts[0] * 60) * 60; # secs contains the sim time in seconds
			
			if( $secs > 100) {
				$state = 1;
			}
		} else {
			# look at ls_req packets from 0.0.1.9
			if(/(.*) 0\.0\.1\.9 > (.*) OSPFv2-ls_req (.*) backbone (.*)/) {
		
				$t = $1;
				# compute actual timestamp
				@ti = split(/:/, $t);
				$act_time = $ti[2] + ($ti[1] + $ti[0] * 60) * 60;
		
				# iterate through the requested LSAs
				$r = $4;
				$r =~ s/{ rtr //g;
				$r =~ s/ }//g;
				@this_req = split(/ /, $r);
				
				$retransmission = 0;
				
				foreach $req (@this_req) {
					
					# retransmission?
					if( exists $request_list{$req} ) {
						$retransmission = 1;
						
						if( ($last_retr ne 0)&&($act_time - $last_retr < 4.5) ) {
							# check if the last_retr was within the last 5 s. (.5s tolerance)
							# if yes, the test will fail
							$state = $state | 2;
						}
						if( $act_time - $request_list{$req} > 5.5 ) { # 0.5s tolerance
							# check if the last request for this LSA was 5s before.
							# if no, the test wil fail
							$state = $state | 4;
						}
						
						# if this was a retransmission, set last_retr
					}
						
					# place the LSA on the request list (with timestamp) or update its timestamp
					$request_list{$req} = $act_time;
				}
				# if this was a retransmission, set last_retr
				if($retransmission eq 1) {
					$last_retr = $act_time;
				}
						
				# now, look at all lsa's on the request list - each of them should have
				# been requested maximally 5s before
				foreach $l (keys %request_list) {
					
					if( $act_time - $request_list{$l} > 5.5 ) {
						$state = $state | 8;
					}
				}
			}
		}
	}

	close( DUMPFILE );
	
	if($state eq 1) {
		$local_verdict[0] = 1;
		print("Retransmissions are sent every RxmtInterval. Test PASSED.\n");
	} else {
		$local_verdict[0] = 2;
		
		if($state & 2) {
			print("Multiple retransmissions in one RxmtInterval. ");
		}
		if($state & 4) {
			print("Retransmision came too late. ");
		}
		if($state & 8) {
			print("Requests were not retransmitted. ");
		}
		print("Test FAILED.\n");
	}
	
}

if($local_verdict[0] eq 3) {
	print("Cannot evaluate results. Test INCONCLUSIVE.\n");
}

$success = 1;
$state = 0;

open(DUMPFILE, $dumpfile2) or $success = 0;

if($success eq 1) {
	while(<DUMPFILE>) {
		# wait 100 s for TR's LSDB to fill
		if($state eq 0) {
			@l = split(/ /, $_);
		
			# now look at the time
			@ti = split(/\./, $l[0]);
			@ts = split(/:/, $ti[0]);
			
			$secs = $ts[2] + ($ts[1] + $ts[0] * 60) * 60; # secs contains the sim time in seconds
			
			if( $secs > 100) {
				$state = 1;
			}
		} else {
			# look at the request packets from 0.0.1.1
			if(/(.*) 0\.0\.1\.1 > (.*) OSPFv2-ls_req (.*) backbone (.*)/) {
		
				# iterate through the requested LSAs
				$r = $4;
				$r =~ s/{ rtr //g;
				$r =~ s/ }//g;
				@this_req = split(/ /, $r);
				
				foreach $req (@this_req) {
					if($req_list2{$req} eq 4711) {
						# this request has already been satisfied -- test fails
						$state = $state | 2;
					} else {
						# add the current timestamp to the hash
						$req_list2{$req} = 1234;
					}
				}
			}
			# now look at updates from 0.0.1.2
			if(/(.*) 0\.0\.1\.2 > (.*) OSPFv2-ls_upd (.*) backbone (.*)/) {
				# iterate through the lsas
				@this_upd = split(/ /, $4);
				
				for($i = 0; $i < $#this_upd; $i++) {
					if($this_upd[$i] eq "rtr") {
						$l = $this_upd[$i+1];
						
						# mark all lsas with the timestamp 4711 in the list
						$req_list2{$l} = 4711;
					}
				}
			}
		}
	}
	
	if($state eq 1) {
		$local_verdict[1] = 1;
		print("Updated LSAs are not requested anymore. Test PASSED.\n");
	} else {
		$local_verdict[1] = 2;
	
		print("Updated LSAs are not removed from Retransmission list. Test FAILED.\n");
	}

	close( DUMPFILE );
}

if($local_verdict[1] eq 3) {
	print("Cannot evaluate results. Test INCONCLUSIVE.\n");
}

$verdict = $local_verdict[0];
if ($local_verdict[1] ne $verdict) {
	if($local_verdict[1] eq 2) {
		$verdict = 2;
	} elsif ($local_verdict[1] eq 3) {
		if($verdict ne 2) {
			$verdict = 3;
		}
	}	
}
#------------------------------------------------------------------------------
print("### VERDICT for $testcase: ");

if ($verdict eq 1) { 
        print("PASS"); 
} elsif ($verdict eq 2) {
        print("FAIL");
} else {
        print("INCONCLUSIVE");
}

print(" ###\n");